﻿using System;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media.Imaging;

namespace PhoneAssistant
{
    /// <summary>
    /// WindowPhoneBeaker.xaml 的交互逻辑
    /// </summary>
    public partial class WindowPhoneBeaker : Window
    {
        /// <summary>
        /// 设备后插入延时执行
        /// </summary>
        private System.Timers.Timer deviceTimer = new System.Timers.Timer(1000);
        /// <summary>
        /// 后台工作类
        /// </summary>
        BackgroundWorker backgroundWorker = new BackgroundWorker();
        /// <summary>
        /// 是否停止刷新界面
        /// </summary>
        private bool isStop = false;
        /// <summary>
        /// 是否存在安卓
        /// </summary>
        private bool HasAndroid = false;
        /// <summary>
        /// 坐标换算乘数
        /// </summary>
        double multiplierX = 0;
        double multiplierY = 0;
        /// <summary>
        /// 屏幕截图文件名称
        /// </summary>
        string tempFileName = "beaker_screen.png";
        /// <summary>
        /// 黑人底部位置
        /// </summary>
        Point Start;
        /// <summary>
        /// 图案中心或者白点位置
        /// </summary>
        Point End;
        /// <summary>
        /// 距离加权，本人手机1.38最优
        /// </summary>
        double press_coefficient = 1.38;
        /// <summary>
        /// 构造方法
        /// </summary>
        public WindowPhoneBeaker()
        {
            InitializeComponent();
            string config = ConfigurationManager.AppSettings["press_coefficient"];
            try
            {
                press_coefficient = Double.Parse(config);
                press_Coefficient_Slider.Value = press_coefficient;
            }
            catch
            {
                Debug.WriteLine("获取距离加权参数出错");
            }
            CheckHasAndroidModel();
            deviceTimer.AutoReset = false;//只需要执行一次
            deviceTimer.Elapsed += (o, e1) => { CheckHasAndroidModel(); };
            //backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.WorkerSupportsCancellation = true;
            backgroundWorker.DoWork += DoWork_Handler;
        }
        #region 窗体基本控制
        /// <summary>
        /// 窗体关闭事件，关闭adb进程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing(object sender, CancelEventArgs e)
        {
            Process[] pro = Process.GetProcesses();//获取已开启的所有进程
            //遍历所有查找到的进程
            for (int i = 0; i < pro.Length; i++)
            {
                //判断此进程是否是要查找的进程
                if (pro[i].ProcessName.ToString().ToLower().Contains("adb"))
                {
                    try
                    {
                        pro[i].Kill();//结束进程
                        break;
                    }catch
                    {
                        Debug.WriteLine("关闭adb进程出错!");
                    }
                    
                }
            }
        }
        /// <summary>
        /// 鼠标左键按下拖动窗口
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="e">路由事件</param>
        private void Title_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.DragMove();
        }
        /// <summary>
        /// 最小化
        /// </summary>
        /// <param name="sender">消息发送者</param>
        /// <param name="e">路由事件</param>
        private void help_button_Click(object sender, RoutedEventArgs e)
        {
            if (tips_Image.Visibility == Visibility.Hidden)
            {
                tips_Image.Visibility = Visibility.Visible;
            }
            else
            {
                tips_Image.Visibility = Visibility.Hidden;
            }
        }
        /// <summary>
        /// 最小化
        /// </summary>
        /// <param name="sender">消息发送者</param>
        /// <param name="e">路由事件</param>
        private void min_button_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }
        /// <summary>
        /// 最大化
        /// </summary>
        /// <param name="sender">消息发送者</param>
        /// <param name="e">路由事件</param>
        private void max_button_Click(object sender, RoutedEventArgs e)
        {
            if (this.WindowState == WindowState.Normal)
            {
                this.WindowState = WindowState.Maximized;
                normal_button.Visibility = Visibility.Visible;
                max_button.Visibility = Visibility.Collapsed;
            }
            else if (this.WindowState == WindowState.Maximized)
            {
                this.WindowState = WindowState.Normal;
                normal_button.Visibility = Visibility.Collapsed;
                max_button.Visibility = Visibility.Visible;
            }
        }
        /// <summary>
        /// 关闭
        /// </summary>
        /// <param name="sender">消息发送者</param>
        /// <param name="e">路由事件</param>
        private void close_button_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
        private void press_Coefficient_Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (press_Coefficient_Slider.Value > 1)
            {
                press_coefficient = press_Coefficient_Slider.Value;
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                //根据Key读取元素的Value
                string name = config.AppSettings.Settings["press_coefficient"].Value;
                //写入元素的Value
                config.AppSettings.Settings["press_coefficient"].Value = press_coefficient.ToString();
                //一定要记得保存，写不带参数的config.Save()也可以
                config.Save(ConfigurationSaveMode.Modified);
                //刷新，否则程序读取的还是之前的值（可能已装入内存）
                ConfigurationManager.RefreshSection("appSettings");
            }            
        }
        #endregion
        #region 处理所有经过窗体的事件
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            this.win_SourceInitialized(this, e);
        }
        void win_SourceInitialized(object sender, EventArgs e)
        {
            HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
            if (hwndSource != null)
            {
                hwndSource.AddHook(new HwndSourceHook(WndProc));
            }
        }
        protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
                case 0x219:
                    Debug.WriteLine("WParam：{0} ,LParam:{1},Msg：{2}，Result：{3}", wParam, lParam, msg, hwnd);
                    if (wParam.ToInt32() == 7)//设备插入或拔出
                    {
                        CheckHasAndroidModel();
                        if (!isStop && HasAndroid&&!deviceTimer.Enabled)
                        {
                            deviceTimer.Start();
                        }
                    }
                        break;
            }
            return IntPtr.Zero;
        }
        #endregion
        #region 手机操控
        /// <summary>
        /// 检测是否存在手机
        /// </summary>
        private void CheckHasAndroidModel()
        {
            var text = "";
            for (int i = 0; i < 3; i++)
            {
                text = cmdAdb("shell getprop ro.product.model", false);//获取手机型号
                if (!(text.Contains("no devices") || text.Contains("not") || text.Contains("doesn't") || string.IsNullOrWhiteSpace(text)))
                    break;
            }
            if (text.Contains("no devices") || text.Contains("not") || text.Contains("doesn't") || string.IsNullOrWhiteSpace(text))
            {
                HasAndroid = false;
                isStop = true;
                Dispatcher.Invoke(
                   new Action(
                        delegate
                        {
                            title_texblock.Text = "手机未连接";
                            screen_image.Source = new BitmapImage(new Uri("\\Resources\\Images\\ads.jpg", UriKind.Relative));
                        }
                   )
                );
                if(deviceTimer.Enabled)
                    deviceTimer.Stop();
            }
            else
            {
                HasAndroid = true;
                isStop = false;
                if (!deviceTimer.Enabled)
                    deviceTimer.Start();
                if (!backgroundWorker.IsBusy)
                {
                    backgroundWorker.RunWorkerAsync();
                }
                Dispatcher.Invoke(
                   new Action(
                        delegate
                        {
                            title_texblock.Text = text;
                        }
                   )
               );
            }
        }
        /// <summary>
        /// 执行adb命令
        /// </summary>
        /// <param name="arguments"></param>
        /// <param name="ischeck"></param>
        /// <returns></returns>
        private string cmdAdb(string arguments, bool ischeck = true)
        {
            if (ischeck && !HasAndroid)
            {
                return string.Empty;
            }
            string ret = string.Empty;
            using (Process p = new Process())
            {
                p.StartInfo.FileName = @"Tools\adb.exe";
                p.StartInfo.Arguments = arguments;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardInput = true;   //重定向标准输入   
                p.StartInfo.RedirectStandardOutput = true;  //重定向标准输出   
                p.StartInfo.RedirectStandardError = true;   //重定向错误输出   
                p.StartInfo.CreateNoWindow = true;
                p.Start();
                ret = p.StandardOutput.ReadToEnd();
                p.Close();
            }
            return ret;
        }

        private void back_button_Click(object sender, RoutedEventArgs e)
        {
            cmdAdb("shell input keyevent 4 ");
        }

        private void home_button_Click(object sender, RoutedEventArgs e)
        {
            cmdAdb("shell input keyevent  3 ");
        }

        private void menu_button_Click(object sender, RoutedEventArgs e)
        {
            cmdAdb("shell input keyevent  82 ");
        }
        #endregion
        #region 后台工作进程
        //后台线程运行的程序
        private void DoWork_Handler(object sender, DoWorkEventArgs args)
        {
            while (true)
            {
                if (isStop)
                {
                    return;
                }
                //死循环截屏获取图片
                cmdAdb("shell screencap -p /sdcard/" + tempFileName);
                cmdAdb("pull /sdcard/" + tempFileName);
                if (System.IO.File.Exists(tempFileName))
                {
                    screen_image.Dispatcher.Invoke(new Action(() =>
                    {
                        try
                        {
                            System.IO.FileStream fs = new System.IO.FileStream(AppDomain.CurrentDomain.BaseDirectory + tempFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                            byte[] buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length);
                            fs.Close(); fs.Dispose();
                            System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer);
                            BitmapImage bitmapImage = new BitmapImage();
                            bitmapImage.BeginInit();
                            bitmapImage.StreamSource = ms;
                            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                            bitmapImage.EndInit();
                            ms.Dispose();
                            screen_image.Source = bitmapImage;
                            if (!(this.Width == bitmapImage.Width || this.Width == bitmapImage.Width * 0.5))
                            {
                                this.Width = (bitmapImage.Width > this.Width ? bitmapImage.Width * 0.5 : bitmapImage.Width);
                                this.Height = (bitmapImage.Height > this.Height ? bitmapImage.Height * 0.5 : bitmapImage.Height) + 80;
                            }
                            if (multiplierX == 0)
                            {
                                multiplierX = screen_image.Source.Width / (screen_image.Width + 0.00);
                                multiplierY = screen_image.Source.Height / (screen_image.Height + 0.00);
                            }
                        }
                        catch
                        {
                            Debug.WriteLine("图片加载或删除出错了");
                        }
                        GC.Collect();
                        if (System.IO.File.Exists(tempFileName))
                        {
                            try
                            {
                                System.IO.File.Delete(tempFileName);
                            }
                            catch
                            {
                                Debug.WriteLine("图片删除出错了");
                            }
                        }
                    }));
                }
            }
        }
        private void screen_image_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
            {
                Start = Mouse.GetPosition(e.Source as FrameworkElement);
            }
            else if (e.ChangedButton == MouseButton.Right)
            {
                End = Mouse.GetPosition(e.Source as FrameworkElement);
                double value = Math.Sqrt(Math.Abs(Start.X - End.X) * Math.Abs(Start.X - End.X) + Math.Abs(Start.Y - End.Y) * Math.Abs(Start.Y - End.Y));
                cmdAdb(string.Format("shell input swipe {0} {1} {2} {3} {4}", Start.X.ToString(), Start.Y.ToString(), End.X.ToString(), End.Y.ToString(),(press_coefficient * 2 * value).ToString("0")));
            }

        }
        #endregion

        
    }
}
